package com.cssl.service.impl;

import cn.dev33.satoken.exception.NotLoginException;
import com.cssl.domain.DtsAddress;
import com.cssl.domain.DtsRegin;
import com.cssl.domain.dto.AddressDto;
import com.cssl.domain.dto.DtsAddressDto;
import com.cssl.mapper.DtsAddressMapper;
import com.cssl.mapper.DtsUserMapper;
import com.cssl.service.DtsAddressService;
import com.cssl.util.*;
import com.fasterxml.jackson.core.type.TypeReference;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author 黄鑫
 * @description 针对表【dts_address(收货地址表)】的数据库操作Service实现
 * @createDate 2024-07-30 11:08:33
 */
@Service
public class DtsAddressServiceImpl
        implements DtsAddressService {
    @Autowired
    private DtsAddressMapper dtsAddressMapper;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private StringRedisTemplate template;
    @Autowired
    private DtsUserMapper userMapper;
    @Autowired
    private ObjectMapperUtil mapperUtil;

    @Override
    public Map getAddressList(DtsAddressDto accountDto) {
        // Redis Key 存储，包含页码和条件
        StringBuilder redisKeyBuilder = new StringBuilder("AddressList");
        if (accountDto.getUserId() != null && accountDto.getUserId() != 0) {
            redisKeyBuilder.append(":UserId:").append(accountDto.getUserId());
        }
        // 检查手机号
        if (accountDto.getName() != null && !accountDto.getName().isEmpty()) {
            redisKeyBuilder.append(":getName:").append(accountDto.getName());
        }
        redisKeyBuilder.append(":page:").append(accountDto.getPageNum());
        String redisKey = redisKeyBuilder.toString();

        List<DtsAddress> addressList = null;

        // 检查 Redis 中是否存在当前页的数据
        if (redisUtil.hasKey(redisKey)) {
            System.out.println("从 Redis 中获取数据");
            addressList = (List<DtsAddress>) redisUtil.get(redisKey);
            Map<String, Object> map1 = new HashMap<>();
            // 获取存储的总数

            map1.put("list", addressList);
            map1.put("total", redisUtil.get("AddressList:total")); // 使用从 Redis 获取的总数
            map1.put("pageNum", accountDto.getPageNum());
            map1.put("pageSize", accountDto.getPageSize());
            return map1;
        } else {
            // 开始分页
            Page page = PageHelper.startPage(accountDto.getPageNum(), accountDto.getPageSize());
            System.out.println("从数据库中查询数据");
            addressList = dtsAddressMapper.getAddressList(accountDto);
            ;
            Map<String, Object> map = new HashMap<>();
            // 计算总数
//            long total = page.getTotal();
            System.out.println("数量地址:"+addressList.size());
            // 将查询结果放入 Redis，设置过期时间，例如：1小时
            redisUtil.set(redisKey, addressList, 3600);
            redisUtil.set("AddressList:total", dtsAddressMapper.getDtsAddressCount(), 3600);

            map.put("list", page.getResult());
            map.put("total", page.getTotal()); // 使用从数据库计算的总数
            map.put("totalPage", page.getPages());
            map.put("pageNum", page.getPageNum());
            map.put("pageSize", page.getPageSize());
            return map;
        }
    }

    @Override
    public Result getUserAddress() {
        //从redis中获取
        Integer login = 0;
        try {
            login = StpKit.USER.getLoginIdAsInt();
        } catch (NotLoginException e) {
            System.out.println("e = " + e);
        }
        Object o = redisUtil.get(StorageVariable.USERADDRESS + ":" + login);

        if (o == null) {
            List<DtsAddress> addressList = dtsAddressMapper.getUserAddress(login);
            redisUtil.set(StorageVariable.USERADDRESS + ":" + login, mapperUtil.toJsonString(addressList), 7 * 24 * 60 * 60);
            return Result.result(InfoCode.OK, InfoCode.MESSAGE_OK, addressList, System.currentTimeMillis());
        }
        List<DtsAddress> addressList = mapperUtil.fromJsonString(o.toString(), new TypeReference<List<DtsAddress>>() {
        });
        return Result.result(InfoCode.OK, InfoCode.MESSAGE_OK, addressList, System.currentTimeMillis());

    }

    @Override
    public Result getNationwide(AddressDto address) {
//        先获得全部省
        List<DtsRegin> provideList = getProvideList();
        List<DtsRegin> cityList = getCityList(address.getProvinceId());
        List<DtsRegin> areaList = getAreaList(address.getCityId());

        Map<String, List<DtsRegin>> map = new HashMap<>();
        map.put("provideList", provideList);
        map.put("cityList", cityList);
        map.put("areaList", areaList);

        return Result.result(InfoCode.OK, InfoCode.MESSAGE_OK, map, System.currentTimeMillis());
    }

    private List<DtsRegin> getProvideList() {
        Object o = redisUtil.get(StorageVariable.PROVINCE);
        if (o != null) {
            return (List<DtsRegin>) o;
        } else {
            List<DtsRegin> provideList = dtsAddressMapper.getProvince();
            redisUtil.set(StorageVariable.PROVINCE, provideList);
            return provideList;
        }
    }

    private List<DtsRegin> getCityList(Integer provinceId) {
        if (provinceId == null || provinceId == 0) {
            return new ArrayList<>();
        }

        String key = StorageVariable.CITY + ":" + provinceId;
        Object o = redisUtil.get(key);
        if (o != null) {
            return (List<DtsRegin>) o;
        } else {
            List<DtsRegin> cityList = dtsAddressMapper.getCity(provinceId);
            redisUtil.set(key, cityList);
            return cityList;
        }
    }

    private List<DtsRegin> getAreaList(Integer cityId) {
        if (cityId == null || cityId == 0) {
            return new ArrayList<>();
        }

        String key = StorageVariable.AREA + ":" + cityId;
        Object o = redisUtil.get(key);
        if (o != null) {
            return (List<DtsRegin>) o;
        } else {
            List<DtsRegin> areaList = dtsAddressMapper.getCity(cityId);
            redisUtil.set(key, areaList);
            return areaList;
        }
    }


    @Override
    public Result getAllNationwide() {
        List<DtsRegin> provideList = getProvideList();

        List<Integer> collect = provideList.stream()
                .map(s -> s.getId())
                .collect(Collectors.toList());

        List<DtsRegin> cityList = dtsAddressMapper.getAllCity(collect);

        List<Integer> collect1 = cityList.stream()
                .map(s -> s.getId())
                .collect(Collectors.toList());

        List<DtsRegin> areaList = dtsAddressMapper.getAllArea(collect1);

        Map map = new HashMap();
        map.put("provideList", provideList);
        map.put("cityList", cityList);
        map.put("areaList", areaList);

        return Result.result(InfoCode.OK, InfoCode.MESSAGE_OK, map, System.currentTimeMillis());
    }


    @Transactional
    @Override
    public Result addUserAddress(DtsAddress address) {
        Integer login = 0;
        try {
            login = StpKit.USER.getLoginIdAsInt();
        } catch (NotLoginException e) {
            System.out.println("e = " + e);
        }
        dtsAddressMapper.updateDefault(login, address.getIsDefault());
        Integer res = dtsAddressMapper.addUserMapper(address);
        if (res != null && res > 0) {
            Set<String> keys = template.keys("AddressList" + "*");
            Set<String> userKeys = template.keys("user" + "*");
            template.delete(keys);
            template.delete(userKeys);
            return Result.result(InfoCode.OK, InfoCode.MESSAGE_OK, true, System.currentTimeMillis());
        }
        return Result.result(InfoCode.FAILED, InfoCode.MESSAGE_FAILED, false, System.currentTimeMillis());
    }


    @Override
    public Result deleteUserAddress(DtsAddress address) {
        Integer res = dtsAddressMapper.deleteUserAddress(address.getId());
        if (res != null && res > 0) {
            Set<String> keys = template.keys("AddressList" + "*");
            Set<String> userKeys = template.keys("user" + "*");
            template.delete(keys);
            template.delete(userKeys);
            return Result.result(InfoCode.OK, InfoCode.MESSAGE_OK, true, System.currentTimeMillis());
        }
        return Result.result(InfoCode.FAILED, InfoCode.MESSAGE_FAILED, false, System.currentTimeMillis());
    }
}




